#include "../hardware/gpio.h"
#include "../drive/sys_timer.h"
#include "io.h"
const static uint8_t mode_table[] = {
    GPIO_Mode_AIN,
    GPIO_Mode_IN_FLOATING,
    GPIO_Mode_IPD,
    GPIO_Mode_IPU,
    GPIO_Mode_Out_OD,
    GPIO_Mode_Out_PP,
    GPIO_Mode_AF_OD,
    GPIO_Mode_AF_PP,
};

void IOInit(uint8_t pin, uint8_t mode) {
    if (pin < PNO)
        GpioInit(pin, (GPIOMode_TypeDef)mode_table[mode]);
}

void IOWrite(uint8_t pin, uint8_t level) {
    if (pin < PNO)
        GpioWrite(pin, level);
}

uint8_t IORead(uint8_t pin) {
    if (pin < PNO)
        return GpioRead(pin);
    return 0;
}

void IODisableJtag() {
    GpioRemap();
}


void SwitchInput::Init(uint8_t pin, uint8_t mode) {
  this->pin_ = pin;
  IOInit(pin, mode);
  this->time_ = CurMillis();
  this->status_ = 0;
  IOWrite(pin, 1);
  this->cur_statu = IORead(this->pin_);
}

bool SwitchInput::CheckStatuLoop() {
  bool ret = false;
  if ((this->time_ + 2) > CurMillis()) {
    return ret;
  }
  // Disappears Shakes
  this->time_ = CurMillis();
  uint8_t cur_statu = IORead(this->pin_);
  this->status_ = (this->status_ << 1) | (cur_statu != 0);
  if (((this->status_ & 0x0f) == 0x0f) || ((this->status_ & 0x0f) == 0x0)) {
    this->cur_statu = this->status_ & 0x1;
  }
  if (this->cur_statu != this->last_statu_) {
    ret = true;
    this->last_statu_ = this->cur_statu;
  }
  return ret;
}

uint8_t SwitchInput::Read() {
  return this->cur_statu;
}

